import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { store } from '/@/store/index.ts';
import { Session } from '/@/utils/storage';
import { dynamicRoutes, staticRoutes } from './route.ts';

// 添加静态路由
export const router = createRouter({
    history: createWebHashHistory(),
    routes: staticRoutes,
});

// 定义404页面
export const pathMatch = {
    path: '/:path(.*)*',
    redirect: '/404',
};

// 后端控制路由-自己
export const routerControl = async (routes: Array<any>) => {
    // 整合路由，将后台返回的meta属性赋值给本地的路由meta权限
    const assignRoutes = await assignRouter(
        dynamicRoutes[0].children,
        formatFlatteningRoutes(routes)
    );

    await setCacheTagsViewRoutes(assignRoutes);

    dynamicRoutes[0].children = assignRoutes;

    //添加动态路由
    router.addRoute(dynamicRoutes[0]);
};

export const setCacheTagsViewRoutes = async (routes: Array<any>) => {
    // 缓存多级嵌套数组处理后的一维数组（将整合好的路由处理成一位数组，用来在tagsView中，整合过滤）
    const tagsViewRoutes = formatFlatteningRoutes(routes);
    formatKeepAliveNames(tagsViewRoutes);

    // 添加到 vuex setTagsViewRoutes 中
    store.dispatch('tagsViewRoutes/setTagsViewRoutes', tagsViewRoutes);
};

// 存储需要缓存的路由的name值
const formatKeepAliveNames = (arr: Array<any>) => {
    const cacheList: Array<string> = [];
    arr.map((v: any) => {
        // 如果路由组件是缓存的，添加到vuex中
        if (v.meta.isKeepAlive) {
            cacheList.push(v.name);
        }
    });
    store.dispatch('keepAliveNames/setKeepAliveNames', cacheList);
};

/**
 * 路由多级嵌套数组处理成一维数组
 * @param arr 传入路由菜单数据数组
 * @returns 返回处理后的一维路由菜单数组
 */
export function formatFlatteningRoutes(arr: any) {
    if (arr.length <= 0) return false;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].children) {
            arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
        }
    }
    return arr;
}

// 整合路由，将后台返回的meta属性赋值给本地的路由meta权限
const assignRouter = async (routes: Array<any>, backRoutes: Array<any>) => {
    return routes.map((item) => {
        const BackItem = backRoutes.filter((k) => k.path == item.path);
        if (BackItem.length > 0) {
            // 获取本地meta属性的所有key值
            const metaKeys = Object.keys(item.meta);
            metaKeys.map((v) => {
                // 判断后台返回的属性中是否在本地中，如果后台返回的属性本地中含有，那么用后台返回的属性，否则用本地自己的属性
                if (BackItem[0].meta.hasOwnProperty(v)) {
                    // 用后台返回的meta属性，如果后台设置了，用后台的；如果没设置，用前台的
                    item.meta[v] = BackItem[0].meta[v];
                }
            });

            item.children && assignRouter(item.children, backRoutes);
            return item;
        }
    });
};

const refreshRoute = async () => {
    const user_id = Session.get('user_id');
    if (user_id) {
        setTimeout(() => {
            // 触发初始化用户信息
            store.dispatch('user/getUserInfo', { user_id });
        }, 0);
    }
};

// 防止页面刷新时，路由丢失
// await initFrontEndControlRoutes();
await refreshRoute();

// 路由加载前
router.beforeEach((to, from, next) => {
    NProgress.configure({ showSpinner: false });
    if (to.meta.title) NProgress.start();
    const token = Session.get('token');
    if (to.path === '/login' && !token) {
        next();
        NProgress.done();
    } else {
        if (!token) {
            // 如果没有token,重定向到登录页面
            next(`/login?redirect=${to.path}`);
            Session.clear();
            // resetRoute();
            NProgress.done();
        } else if (token && to.path === '/login') {
            next('/home');
            NProgress.done();
        } else {
            next();
        }
    }
});

// 路由加载后
router.afterEach(() => {
    NProgress.done();
});

// 导出路由
export default router;
